#!/usr/bin/perl -w
use strict;
#Copyright 2011. Jason Weirather.
#This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3 or any later version.
#open NET, "/Users/weirathe/Code/VSGanalysis/Graphmaking/ThreePartBreakup/networkMap.txt";
#open TEST, ">test.txt";
# take the filename of the network map as the command line argument
our $infilename = shift @ARGV;
open(INFILE, $infilename) or die "couldn't open $infilename\n";
chomp(my @nets = <INFILE>);
close INFILE;
my $random_seed = shift(@ARGV);
srand($random_seed);
my $inlabel = shift @ARGV;

my $table_line = shift @nets;
my @tables = split(/\s+/,$table_line);
my $tableName = $tables[1];
my $type_line = shift @nets;
my $Eval = shift @nets;
my $GapWindoSize = shift @nets;
my $header_line = shift @nets;
my $nodeFontSize;
my $nodeHeight;
my $nodeWidth;
my $graphSize;


my %VSGs;
my @IDs;
my %Chromosomes;

my $filename = "$infilename.dot";

print_file(\@nets,$filename);






sub print_type {
  my @nets = @_;
  my $do3D = 1;
  if($graphSize ne '') { print "\tsize = $graphSize;\n"; }
  my %colorMapNtype = (
    1 => '#e31a1c',
    4 => '#377db8',
    2 => '#4daf4a',
    3 => '#984ea3',
    5 => '#ff7f00',
    0 => '#fbb3ad'
  ); 

  my @outputs;
  # we need to get the IDs from the nets
  my %nodes;
  my %types;
  foreach my $net (@nets) {
    my @fields = split(/\t/,$net);
    if($fields[1] eq '_blank' || $fields[3] eq '_blank') { die "'_blank' is a bar word, don't use it as a label.\n" }
    if(!exists($fields[1])) { $fields[1] = '_blank';}
    $nodes{$fields[0]} = $fields[1];
    if(exists($types{$fields[1]})) { $types{$fields[1]}->{$fields[0]} = 1; }
    else { # make a new hash
      my %newtype;
      $newtype{$fields[0]} = 1;
      $types{$fields[1]} = \%newtype;
    }
    if(!exists($fields[3])) { $fields[3] = '_blank';}
    $nodes{$fields[2]} = $fields[3];
    if(exists($types{$fields[3]})) { $types{$fields[3]}->{$fields[2]} = 1; }
    else { # make a new hash
      my %newtype;
      $newtype{$fields[2]} = 1;
      $types{$fields[3]} = \%newtype;
    }
  } # now roughly speaking each id is labeled
  
  my %ColorMap;
  open(LEGEND,">$infilename.legend") or die "couldn't open $infilename.legend";
  foreach my $type (keys(%types)) {
    $ColorMap{$type} = sprintf "#%x%x%x%x%x%x", map { rand(16) } 1 .. 6;
    print LEGEND "$type\t$ColorMap{$type}\n";
  }
  close LEGEND;
  foreach my $type (keys(%types)) {
    ####print "\t{ ";
    ####print "\t";
    ###editing here to break these up
    foreach my $node (keys(%{$types{$type}})) { # for all the nodes of a particular type
      my $output = ""; 
      $output.= "\"$node\" ";  # if it is of this type, print it here

      $output .= "[";
      $output .= "label=\"$node\", ";
      if($inlabel eq 'nolabel') { $output .= "shape = point, "; } #was point
      else { $output.= "shape = ellipse, "; } #ellipse here 
      $output .= "layer = 1,";
      $nodeFontSize = 4;
      $output .= "fontsize = $nodeFontSize, ";
      if($nodeHeight) { $output .= "height = $nodeHeight, "; }
      if($nodeWidth) { $output .= "width = $nodeWidth, "; } 
      $output .= "style = filled, fillcolor=\"$ColorMap{$type}\"];";
      push @outputs, $output;
    }
  }
  # randomize output order
  shuffleArray(\@outputs);  # is this still necessary?
  foreach my $output (@outputs) { print "$output\n"; }
}
    
sub shuffleArray { # take the reference to an array as an argument
  srand(9001); #seed the random number generator
  my $arrayref = shift;
  my $index = @$arrayref;
  while($index--) {
    my $newloc = int rand(1+$index);
    @$arrayref[$index,$newloc] = @$arrayref[$newloc,$index];
  }
}

sub print_file {
  my $labelEdges = 0; # if 0 don't label edges  
  my $minimumEdgeFontSize = 6;
  my $rangeEdgeFontSize = 4;
  my $minimumEdgeColor = 75; #Zero-100
  ### for C terminus try nodeFontSize 0, nodeHeight 0.1, nodeWidth 0.1
  $nodeFontSize = 2;  # 10 normal 0 for strange
  $nodeHeight = 0.2; #if commented out then don't use
  $nodeWidth = 0.2; # if commented out don't use
  $graphSize = ""; # bounding box in inches
  my $invisibleEdge = 0;
  my $colorType = "Type";
  ####colorType choices are:
  ########################## Chromosome
  ########################## Type (ntype or ctype depending on which you loaded)
  ########################## Function (Functional/atypical/pseudogene)

  # this function prints to the file name given to it through the variable filename
  my ($nets_ref,$filename) = @_; 
  my @nets = @{$nets_ref};
  ##comeback###open(STDOUT,">$filename") or die "Cannot open $filename";
print "graph G {\n";
#we may want to do this based on contigs rather than Chromosome at some point

###print "\t[outputOrder = \"edgesfirst\"];\n";
#print "layers = \"bottom:top\";\n";
#print "\tOutputOrder = \"EdgesFirst\";\n";
###print "\tnode [layer = \"top\"];\n";
###print "\tedge [layer =\"bottom\"];\n";
####print "\tlayers = \"top:middle:bottom\";\n";  # these are the layers we can use in any function
####print "\tnode [layer = \"top\"];\n";

#print_type(@nets);

my @connections;
my $maxRawScore = 0;
my $minRawScore = 1000000000;
foreach my $net(@nets) { 
  my @net = split(/\t/,$net);
  my ($node, $target) = ($net[0], $net[2]);
  push @connections, \@net; #add a net entry to the connections list
  # find the maximums of parameters and some counts here.
  #if($net[4] =~ /e-/) { $net[4] = 0; }
  if($net[4] > $maxRawScore) { $maxRawScore = $net[4]; }
  if($net[4] < $minRawScore) { $minRawScore = $net[4]; }
}
my $rawScoreRange = $maxRawScore - $minRawScore;
#print TEST "$maxRawScore\t$minRawScore\n$rawScoreRange\n";
my %doneConnection; # Use this so we don't repeat, it looks like pairs are usually the same so this is A-OK
####print "\tedge [layer = \"bottom\"];\n";
my @pouts;
foreach my $connection(@connections) {
  if(!exists($doneConnection{"$connection->[0]\t$connection->[2]"})) {
    my $pout;
    $pout .= "\t\"$connection->[0]\"--\"$connection->[2]\"";
    $pout .= " [";
    # add in dashed or dotted for gaps
    my $dashThreshold = 300; # more than this go dotted #set at 300 to limit it to dashed and solid
    if($invisibleEdge == 1) { $pout .= "style = invis,"; }
    #$pout .= "";
    my $color;
    if($rawScoreRange != 0) {
      $color = (($connection->[4]-$minRawScore)/$rawScoreRange);
    } else { $color = 1; }
    #print TEST "$color\n";    
    $color = ($color - 1) * -1;
    $color = $color * (100-$minimumEdgeColor); # now is between 0 and 100
    $color = sprintf("%d",$color);
    #print TEST "score: $connection->[4]\tcolor: $color\n";
    $pout .= "color=\"grey$color\"";
    #$pout .= ",fontcolor=\"blue\"";
    $pout .= ",layer=2";

    #if($labelEdges == 1) {  # we want to label every edge
    #  $pout .= ",label=\"$connection->[10] / $identity";
    #  $pout .= "\"";
    #  $pout .= "];";
    #} else { $pout .= "];"; } #in case we aren't labeling the edges
    $pout .= "];"; 
    push @pouts, $pout;
    $doneConnection{"$connection->[0]\t$connection->[2]"} = 1; # order is important here for doneConnection
    $doneConnection{"$connection->[2]\t$connection->[0]"} = 1; # order is important here for doneConnection
  }
}
print_type(@nets);
shuffleArray(\@pouts);
foreach my $pout (@pouts) { print "$pout\n"; }
print "}\n"; # the end
close STDOUT;

}
